package com.clouddisk.web.controller.system;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.RandomUtil;
import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.clouddisk.common.annotation.Log;
import com.clouddisk.common.core.controller.BaseController;
import com.clouddisk.common.core.domain.R;
import com.clouddisk.common.core.domain.dto.sharefile.*;
import com.clouddisk.common.core.domain.entity.Share;
import com.clouddisk.common.core.domain.entity.ShareFile;
import com.clouddisk.common.core.domain.entity.UserFile;
import com.clouddisk.common.enums.BusinessType;
import com.clouddisk.common.utils.FilesUtils;
import com.clouddisk.system.component.FileDealComp;
import com.clouddisk.system.domain.vo.share.ShareFileListVO;
import com.clouddisk.system.domain.vo.share.ShareFileVO;
import com.clouddisk.system.domain.vo.share.ShareListVO;
import com.clouddisk.system.domain.vo.share.ShareTypeVO;
import com.clouddisk.system.service.IShareFileService;
import com.clouddisk.system.service.IShareService;
import com.clouddisk.system.service.IUserFileService;
import com.qiwenshare.common.util.DateUtil;
import lombok.RequiredArgsConstructor;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.text.ParseException;
import java.util.*;

/**
 * 文件分享接口
 * @author ZJH
 */
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/system/share")
public class SysShareController extends BaseController {

    @Resource
    IShareFileService shareFileService;
    @Resource
    IShareService shareService;
    @Resource
    IUserFileService userFileService;
    @Resource
    FileDealComp fileDealComp;

    @Log(title = "分享文件", businessType = BusinessType.INSERT)
    @PostMapping(value = "/sharefile")
    @ResponseBody
    public R<ShareFileVO> shareFile(@RequestBody ShareFileDTO shareSecretDTO) {
        ShareFileVO shareSecretVO = new ShareFileVO();
        String uuid = UUID.randomUUID().toString().replace("-", "");
        Share share = new Share();
        BeanUtil.copyProperties(shareSecretDTO, share);
        share.setShareTime(DateUtil.getCurrentTime());
        share.setUserId(getUserId());
        share.setShareStatus(0);
        if (shareSecretDTO.getShareType() == 1) {
            String extractionCode = RandomUtil.randomNumbers(6);
            share.setExtractionCode(extractionCode);
            shareSecretVO.setExtractionCode(share.getExtractionCode());
        }
        share.setShareBatchNum(uuid);
        shareService.save(share);
        List<ShareFile> fileList = JSON.parseArray(shareSecretDTO.getFiles(), ShareFile.class);
        List<ShareFile> saveFileList = new ArrayList<>();
        for (ShareFile shareFile : fileList) {
            UserFile userFile = userFileService.getById(shareFile.getUserFileId());
            if (userFile.getUserId().compareTo(getUserId()) != 0) {
                return R.fail("您只能分享自己的文件");
            }
            if (userFile.getIsDir() == 1) {
                FilesUtils filesUtils = new FilesUtils(userFile.getFilePath(), userFile.getFileName(), true);
                List<UserFile> userfileList = userFileService.selectUserFileByLikeRightFilePath(filesUtils.getPath(), getUserId(),shareFile.getFileDeptName());
                for (UserFile userFile1 : userfileList) {
                    ShareFile shareFile1 = new ShareFile();
                    shareFile1.setUserFileId(userFile1.getUserFileId());
                    shareFile1.setShareBatchNum(uuid);
                    shareFile1.setShareFilePath(userFile1.getFilePath().replaceFirst(userFile.getFilePath().equals("/") ? "" : userFile.getFilePath(), ""));
                    saveFileList.add(shareFile1);
                }
            }
            shareFile.setShareFilePath("/");
            shareFile.setShareBatchNum(uuid);
            saveFileList.add(shareFile);
        }
        shareFileService.batchInsertShareFile(saveFileList);
        shareSecretVO.setShareBatchNum(uuid);
        return R.ok(shareSecretVO);
    }

    @PostMapping(value = "/savesharefile")
    @Transactional(rollbackFor=Exception.class)
    @ResponseBody
    public R<String> saveShareFile(@RequestBody SaveShareFileDTO saveShareFileDTO) {
        List<ShareFile> fileList = JSON.parseArray(saveShareFileDTO.getFiles(), ShareFile.class);
        String savefilePath = saveShareFileDTO.getFilePath();
        Long userId = getUserId();
        List<UserFile> saveUserFileList = new ArrayList<>();
        for (ShareFile shareFile : fileList) {
            UserFile userFile = userFileService.getById(shareFile.getUserFileId());
            String fileName = userFile.getFileName();
            String savefileName = fileDealComp.getRepeatFileName(userFile, savefilePath);
            if (userFile.getIsDir() == 1) {
                List<UserFile> userfileList = userFileService.selectUserFileByLikeRightFilePath(
                    new FilesUtils(userFile.getFilePath(), userFile.getFileName(), true).getPath(),
                    userFile.getUserId(),userFile.getFileDeptName());
                // log.info("查询文件列表：" + JSON.toJSONString(userfileList));
                String filePath = userFile.getFilePath();
                userfileList.forEach(p->{
                    p.setUserFileId(null);
                    p.setUserId(userId);
                    p.setFilePath(p.getFilePath().replaceFirst(filePath + "/" + fileName, savefilePath + "/" + savefileName));
                    saveUserFileList.add(p);
                    // log.info("当前文件：" + JSON.toJSONString(p));
                });
            }
            userFile.setUserFileId(IdUtil.getSnowflakeNextIdStr());
            userFile.setUserId(userId);
            userFile.setFilePath(savefilePath);
            userFile.setFileName(savefileName);
            saveUserFileList.add(userFile);
        }
        // log.info("----------" + JSON.toJSONString(saveUserFileList));
        userFileService.saveBatch(saveUserFileList);
        return R.ok();
    }

    @Log(title = "查看已分享列表", businessType = BusinessType.OTHER)
    @GetMapping(value = "/shareList")
    @ResponseBody
    public R<Map<String,Object>> shareList(ShareListDTO shareListDTO) {
        List<ShareListVO> shareList = shareService.selectShareList(shareListDTO,getUserId());
        int total = shareService.selectShareListTotalCount(shareListDTO,getUserId());
        Map<String, Object> map = new HashMap<>();
        map.put("total", total);
        map.put("list", shareList);
        return R.ok(map);
    }

    @Log(title = "取消分享", businessType = BusinessType.DELETE)
    @PostMapping(value = "/shareCancel")
    @ResponseBody
    public R<String> shareCancel(@RequestBody ShareCancelFileDTO shareCancelFileDTO) {
        shareService.selectCancelShareList(shareCancelFileDTO,getUserId());
        return R.ok();
    }

    @GetMapping(value = "/sharefileList")
    @ResponseBody
    public R<List<ShareFileListVO>> shareFileList(ShareFileListDTO shareFileListBySecretDTO) {
        String shareBatchNum = shareFileListBySecretDTO.getShareBatchNum();
        String shareFilePath = shareFileListBySecretDTO.getShareFilePath();
        List<ShareFileListVO> list = shareFileService.selectShareFileList(shareBatchNum, shareFilePath);
        for (ShareFileListVO shareFileListVO : list) {
            shareFileListVO.setShareFilePath(shareFilePath);
        }
        return R.ok(list);
    }

    @GetMapping(value = "/sharetype")
    @ResponseBody
    public R<ShareTypeVO> shareType(ShareTypeDTO shareTypeDTO) {
        LambdaQueryWrapper<Share> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(Share::getShareBatchNum, shareTypeDTO.getShareBatchNum());
        Share share = shareService.getOne(lambdaQueryWrapper);
        ShareTypeVO shareTypeVO = new ShareTypeVO();
        shareTypeVO.setShareType(share.getShareType());
        return R.ok(shareTypeVO);
    }

    @GetMapping(value = "/checkextractioncode")
    @ResponseBody
    public R<String> checkExtractionCode(CheckExtractionCodeDTO checkExtractionCodeDTO) {
        LambdaQueryWrapper<Share> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(Share::getShareBatchNum, checkExtractionCodeDTO.getShareBatchNum())
            .eq(Share::getExtractionCode, checkExtractionCodeDTO.getExtractionCode());
        List<Share> list = shareService.list(lambdaQueryWrapper);
        if (list.isEmpty()) {
            return R.fail("校验失败");
        } else {
            return R.ok();
        }
    }

    @GetMapping(value = "/checkendtime")
    @ResponseBody
    public R<String> checkEndTime(CheckEndTimeDTO checkEndTimeDTO) {
        LambdaQueryWrapper<Share> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(Share::getShareBatchNum, checkEndTimeDTO.getShareBatchNum());
        Share share = shareService.getOne(lambdaQueryWrapper);
        if (share == null) {
            return R.fail("文件不存在！");
        }
        String endTime = share.getEndTime();
        Date endTimeDate = null;
        try {
            endTimeDate = DateUtil.getDateByFormatString(endTime, "yyyy-MM-dd HH:mm:ss");
        } catch (ParseException e) {
            // log.error("日期解析失败：{}" , e);
        }
        if (new Date().after(endTimeDate))  {
            return R.fail("分享已过期");
        } else {
            return R.ok();
        }
    }
}
